package com.lsyw.intergrate.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lsyw.intergrate.common.StringUtil;
import com.lsyw.intergrate.common.util.DateUtil;
import com.lsyw.intergrate.entity.*;
import com.lsyw.intergrate.entity.qo.WaterQo;
import com.lsyw.intergrate.entity.qo.WaterTrendQo;
import com.lsyw.intergrate.service.*;
import io.swagger.annotations.ApiOperation;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.lsyw.intergrate.entity.common.PageInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lsyw.intergrate.common.Result;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import io.swagger.annotations.Api;

import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 设备信息表 前端控制器
 * </p>
 *
 * @author 刘磊
 * @since 2023-12-18
 */
@Api(tags = "水站数据表")
@RestController
@RequestMapping("/device-data-virtural")
public class DeviceDataVirtualController {


    @Autowired
    private DeviceDataVirtualService deviceDataVirtualService;
    @Autowired
    private DeviceDataVirtualDataService deviceDataVirtualDataService;
    @Autowired
    private JcMassifFactorValueLogService jcMassifFactorValueLogService;
    @Autowired
    private JcMassifFactorValueService jcMassifFactorValueService;
    @Autowired
    private JcFactorService jcFactorService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private MassifService massifService;

    /*  *//**
     * 分页查询
     *//*
    @PostMapping("/test")
    public Result test() {
        final LambdaQueryWrapper<DeviceDataVirtual> lambda = new QueryWrapper<DeviceDataVirtual>().lambda();
        lambda.eq(DeviceDataVirtual::getDelFlag,0);
        lambda.orderByAsc(DeviceDataVirtual::getMonitorDate);
        List<DeviceDataVirtual> dataVirtualList=deviceDataVirtualService.list(lambda);
        dataVirtualList.forEach(e->{
            DeviceDataVirtualData dph = new DeviceDataVirtualData();
            dph.setDeviceNo("1");
            dph.setDeviceDataVirtualId(e.getId());
            dph.setFactorValue(e.getPh());
            dph.setJcFactorId("w01001");
            dph.setGmtCreate(e.getGmtCreate());
            dph.setDelFlag(0);
            deviceDataVirtualDataService.save(dph);
            DeviceDataVirtualData hxxyl = new DeviceDataVirtualData();
            hxxyl.setDeviceNo("1");
            hxxyl.setDeviceDataVirtualId(e.getId());
            hxxyl.setFactorValue(e.getHxxyl());
            hxxyl.setJcFactorId("w01018");
            hxxyl.setGmtCreate(e.getGmtCreate());
            hxxyl.setDelFlag(0);
            deviceDataVirtualDataService.save(hxxyl);
            DeviceDataVirtualData zd = new DeviceDataVirtualData();
            zd.setDeviceNo("1");
            zd.setDeviceDataVirtualId(e.getId());
            zd.setFactorValue(e.getZd());
            zd.setJcFactorId("w21001");
            zd.setGmtCreate(e.getGmtCreate());
            zd.setDelFlag(0);
            deviceDataVirtualDataService.save(zd);
            DeviceDataVirtualData ad = new DeviceDataVirtualData();
            ad.setDeviceNo("1");
            ad.setDeviceDataVirtualId(e.getId());
            ad.setFactorValue(e.getAd());
            ad.setJcFactorId("w21003");
            ad.setGmtCreate(e.getGmtCreate());
            ad.setDelFlag(0);
            deviceDataVirtualDataService.save(ad);
            DeviceDataVirtualData zl = new DeviceDataVirtualData();
            zl.setDeviceNo("1");
            zl.setDeviceDataVirtualId(e.getId());
            zl.setFactorValue(e.getZl());
            zl.setJcFactorId("w21011");
            zl.setGmtCreate(e.getGmtCreate());
            zl.setDelFlag(0);
            deviceDataVirtualDataService.save(zl);
        });

        return Result.successResult(null);
    }*/

    /**
     * 分页查询
     */
    @PostMapping("/page")
    public Result page(@RequestBody PageInfo pageInfo) {
        Page<DeviceDataVirtual> page = new Page<>();
        page.setSize(pageInfo.getPageSize());
        page.setCurrent(pageInfo.getPageNum());
        if (pageInfo.getCondition().get("deviceId") == null || Objects.equals(pageInfo.getCondition().get("deviceId").toString(), "")) {
            return Result.successResult(null);
        }
        IPage<DeviceDataVirtual> iPage = this.deviceDataVirtualService.getPage(page, pageInfo.getCondition());
        List<DeviceDataVirtualData> dataList = this.deviceDataVirtualDataService.getList(pageInfo.getCondition());
        List<Map<String, Object>> headerList = new ArrayList<>();
        Map<String, Object> nameMap = new HashMap<>();
        nameMap.put("name", "站点名称");
        nameMap.put("key", "siteName");
        headerList.add(nameMap);
        Map<String, Object> dateMap = new HashMap<>();
        dateMap.put("name", "监测时间");
        dateMap.put("key", "monitorDate");
        headerList.add(dateMap);
        List<JcFactor> jcFactorList = jcFactorService.getListByDeviceId(pageInfo.getCondition().get("deviceId").toString());
        jcFactorList.forEach(e -> {
            Map<String, Object> typeMap = new HashMap<>();
            typeMap.put("name", e.getName() + "(" + e.getUnitMeasurement() + ")");
            typeMap.put("key", e.getId());
            headerList.add(typeMap);
        });

        List<Map<String, Object>> bodyList = new ArrayList<>();
        iPage.getRecords().forEach(e -> {
            Map<String, Object> map = new HashMap<>();
            map.put("siteName", e.getSiteName());
            map.put("monitorDate", DateUtil.formatTime(e.getMonitorDate()));
            jcFactorList.forEach(k -> {
                Optional<DeviceDataVirtualData> mapOptional = dataList.stream().filter(b -> (
                                b.getDeviceDataVirtualId().equals(e.getId()) &&
                                        b.getJcFactorId().equals(k.getId())
                        )
                ).findFirst();
                if (mapOptional.isPresent()) {
                    DeviceDataVirtualData deviceDataVirtualData = mapOptional.get();
                    map.put(k.getId(), deviceDataVirtualData.getFactorValue());
                } else {
                    map.put(k.getId(), 0);
                }
            });
            bodyList.add(map);

        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("header", headerList);
        jsonObject.put("body", bodyList);
        jsonObject.put("page", iPage);
        return Result.successResult(jsonObject);
    }

    /**
     * 分页查询
     */
    @ApiOperation(value = "水质数据监测")
    @PostMapping("/waterMonitor")
    public Result waterMonitor(@RequestBody WaterQo waterQo) {
        if (Objects.isNull(waterQo) || CollectionUtils.isEmpty(waterQo.getIdList()) || StringUtil.isEmpty(waterQo.getDate())) {
            Result.errorResult("参数错误");
        }
        JSONObject dataJson = new JSONObject();
        List<String> dateList = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            for (int j = 0; j < 60; j++) {
                String dateStr = "";
                if (i < 10) {
                    dateStr += "0" + i + ":";
                } else {
                    dateStr += i + ":";
                }
                if (j < 10) {
                    dateStr += "0" + j;
                } else {
                    dateStr += j;
                }
                dateList.add(dateStr);
            }
        }
        dataJson.put("dateList", dateList);

        List<JcFactor> jcFactorList = jcFactorService.getListByDeviceList(waterQo.getIdList());
        List<JSONObject> factorStackedLineChartList = new ArrayList<>();
        jcFactorList.forEach(e -> {
            JSONObject jcFactorJson = new JSONObject();
            jcFactorJson.put("factorName", e.getName());
            jcFactorJson.put("unit", e.getUnitMeasurement());
            List<JSONObject> chartDataList = new ArrayList<>();
            waterQo.getIdList().forEach(k -> {
                Map<String, Object> condition = new HashMap<>();
                condition.put("startTime", waterQo.getDate() + " 00:00:00");
                condition.put("endTime", waterQo.getDate() + " 23:59:59");
                condition.put("deviceId", k);
                condition.put("jcFactorId", e.getId());
                condition.put("dateForm", "'%Y-%m-%d %h:%i'");
                List<Map<String, Object>> dataList = this.deviceDataVirtualDataService.getListGroupDate(condition);
                Map<String, Double> valueMap = new HashMap<>();
                for (Map<String, Object> itemMap : dataList) {
                    if (itemMap.get("date") != null) {
                        valueMap.put(itemMap.get("date").toString(), Double.parseDouble(itemMap.get("factorValue").toString()));
                    }
                }
                List<String> jcFactorIdList = jcFactorService.getListByDeviceId(k).stream().map(JcFactor::getId).collect(Collectors.toList());
                if (jcFactorIdList.contains(e.getId())) {
                    JSONObject chartDataJson = new JSONObject();
                    Device device = deviceService.getById(k);
                    chartDataJson.put("name", device.getName());
                    List<String> valueList = new ArrayList<>();
                    dateList.forEach(l -> {
                        if (valueMap.get(waterQo.getDate() + " " + l) != null) {
                            valueList.add(valueMap.get(waterQo.getDate() + " " + l) + "");
                        } else {
                            valueList.add("0");
                        }
                    });

                    chartDataJson.put("data", valueList);
                    chartDataList.add(chartDataJson);
                }
            });
            jcFactorJson.put("chartDataList", chartDataList);
            factorStackedLineChartList.add(jcFactorJson);


        });
        dataJson.put("factorStackedLineChartList", factorStackedLineChartList);

        return Result.successResult(dataJson);
    }

    /**
     * 分页查询
     */
    @ApiOperation(value = "水质趋势分析-图表")
    @PostMapping("/waterTrend")
    public Result waterTrend(@RequestBody WaterTrendQo waterTrendQo) {
        if (Objects.isNull(waterTrendQo) || StringUtil.isEmpty(waterTrendQo.getSiteId()) || StringUtil.isEmpty(waterTrendQo.getStartDate()) || StringUtil.isEmpty(waterTrendQo.getEndDate())) {
            Result.errorResult("参数不能为空");
        }
        String dateType="'%Y-%m-%d'";
        JSONObject dataJson = new JSONObject();
        JSONObject topJson = new JSONObject();
        JSONObject downJson = new JSONObject();
        List<String> dateTrendList = new ArrayList<>();
        List<String> dateTableList = new ArrayList<>();
        Date startTime = DateUtil.getDayStartTime(DateUtil.parseDate(waterTrendQo.getStartDate()));

        Date endTime = DateUtil.getDayEndTime(DateUtil.parseDate(waterTrendQo.getEndDate()));

        Date addTime = DateUtil.getDayStartTime(DateUtil.parseDate(waterTrendQo.getStartDate()));
        while (addTime.compareTo(endTime) < 1) {
            if (waterTrendQo.getType() == 1) {
                dateTrendList.add(DateUtil.format(addTime, "MM-dd HH"));
                dateTableList.add(DateUtil.format(addTime, "YYYY-MM-dd HH"));
                addTime=DateUtil.addHour(addTime, 1);
            } else {
                dateTrendList.add(DateUtil.format(addTime, "MM-dd"));
                dateTableList.add(DateUtil.format(addTime, "YYYY-MM-dd"));
                addTime=DateUtil.addDays(addTime, 1);
            }

        }

        List<Map<String, Object>> headerList = new ArrayList<>();
        Map<String, Object> nameMap = new HashMap<>();
        nameMap.put("name", "站点名称");
        nameMap.put("key", "siteName");
        headerList.add(nameMap);
        Map<String, Object> dateMap = new HashMap<>();
        dateMap.put("name", "监测时间");
        dateMap.put("key", "monitorDate");
        headerList.add(dateMap);
        List<JcFactor> jcFactorList = jcFactorService.getListByDeviceId(waterTrendQo.getSiteId());
        jcFactorList.forEach(e -> {
            Map<String, Object> typeMap = new HashMap<>();
            typeMap.put("name", e.getName() + "(" + e.getUnitMeasurement() + ")");
            typeMap.put("key", e.getId());
            headerList.add(typeMap);
        });
        Device device = deviceService.getById(waterTrendQo.getSiteId());
        if (waterTrendQo.getType() == 1) {
            dateType = "'%Y-%m-%d %h'";
        }
        List<Map<String, Object>> bodyList = new ArrayList<>();
        Map<String, Object> condition = new HashMap<>();
        condition.put("startTime", DateUtil.formatTime(startTime));
        condition.put("endTime", DateUtil.formatTime(endTime));
        condition.put("dateForm", dateType);
        condition.put("deviceId", waterTrendQo.getSiteId());
        List<Map<String, Object>> dataList = this.deviceDataVirtualDataService.getListGroupDateAndType(condition);
        dateTableList.forEach(e -> {
            Map<String, Object> map = new HashMap<>();
            map.put("siteName", device.getName());
            map.put("monitorDate", e);
            jcFactorList.forEach(k -> {
                List<Map<String, Object>> mapList = dataList.stream().filter(b -> (
                                b.get("date").equals(e)
                        )
                ).collect(Collectors.toList());
                Map<String, Double> valueMap = new HashMap<>();
                for (Map<String, Object> itemMap : mapList) {
                    if (itemMap.get("jcFactorId") != null) {
                        valueMap.put(itemMap.get("jcFactorId").toString(), Double.parseDouble(itemMap.get("factorValue").toString()));
                    }
                }
                if (valueMap.get(k.getId()) != null) {
                    map.put(k.getId(), valueMap.get(k.getId()));
                } else {
                    map.put(k.getId(), 0);
                }
            });
            bodyList.add(map);

        });
        topJson.put("dateList", dateTrendList);
        List<JSONObject> factorStackedLineChartList = new ArrayList<>();
        jcFactorList.forEach(e -> {
            JSONObject jcFactorJson = new JSONObject();
            jcFactorJson.put("factorName", e.getName());
            jcFactorJson.put("unit", e.getUnitMeasurement());
            Map<String, Double> valueMap = new HashMap<>();
            List<Map<String, Object>> mapList = dataList.stream().filter(b -> (
                            b.get("jcFactorId").equals(e.getId())
                    )
            ).collect(Collectors.toList());
            for (Map<String, Object> itemMap : mapList) {
                if (itemMap.get("date") != null) {
                    valueMap.put(itemMap.get("date").toString(), Double.parseDouble(itemMap.get("factorValue").toString()));
                }
            }
            List<String> valueList = new ArrayList<>();
            dateTableList.forEach(l -> {
                if (valueMap.get(l) != null) {
                    valueList.add(valueMap.get(l) + "");
                } else {
                    valueList.add("0");
                }
            });

            jcFactorJson.put("data", valueList);
            factorStackedLineChartList.add(jcFactorJson);


        });
        topJson.put("factorStackedLineChartList", factorStackedLineChartList);


        downJson.put("header", headerList);
        downJson.put("body", bodyList);
        dataJson.put("top", topJson);
        dataJson.put("down", downJson);
        return Result.successResult(dataJson);
    }
    /**
     * 环境历史监测导出
     */
    @ApiOperation(value = "水质趋势分析-导出")
    @PostMapping("/waterTrendExcel")
    public void waterTrendExcel(@RequestBody WaterTrendQo waterTrendQo, HttpServletResponse response) throws IOException {
        if (Objects.isNull(waterTrendQo) || StringUtil.isEmpty(waterTrendQo.getSiteId()) || StringUtil.isEmpty(waterTrendQo.getStartDate()) || StringUtil.isEmpty(waterTrendQo.getEndDate())) {
            Result.errorResult("参数不能为空");
        }
        JSONObject jsonObject = new JSONObject();
        Device device = deviceService.getById(waterTrendQo.getSiteId());
        Massif massif = massifService.getById(device.getMassifId());
        List<List<String>> headerList = new ArrayList<>();
        headerList.add(Collections.singletonList("项目名称"));
        headerList.add(Collections.singletonList("站点名称"));
        headerList.add(Collections.singletonList("监测时间"));
        List<JcFactor> jcFactorList = jcFactorService.getListByDeviceId(waterTrendQo.getSiteId());
        jcFactorList.forEach(e -> {
            headerList.add(Collections.singletonList(e.getName() + "(" + e.getUnitMeasurement() + ")"));
        });

        List<List<String>> bodyList = new ArrayList<>();
        Date startTime = DateUtil.getDayStartTime(DateUtil.parseDate(waterTrendQo.getStartDate()));

        Date endTime = DateUtil.getDayEndTime(DateUtil.parseDate(waterTrendQo.getEndDate()));
        Date addTime = DateUtil.getDayStartTime(DateUtil.parseDate(waterTrendQo.getStartDate()));
        List<String> dateTableList = new ArrayList<>();
        while (addTime.compareTo(endTime) < 1) {
            if (waterTrendQo.getType() == 1) {
                dateTableList.add(DateUtil.format(addTime, "YYYY-MM-dd HH"));
                addTime=DateUtil.addHour(addTime, 1);
            } else {
                dateTableList.add(DateUtil.format(addTime, "YYYY-MM-dd"));
                addTime=DateUtil.addDays(addTime, 1);
            }

        }
        String dateType="'%Y-%m-%d'";

        if (waterTrendQo.getType() == 1) {
            dateType = "'%Y-%m-%d %h'";
        }
        Map<String, Object> condition = new HashMap<>();
        condition.put("startTime", DateUtil.formatTime(startTime));
        condition.put("endTime", DateUtil.formatTime(endTime));
        condition.put("dateForm", dateType);
        condition.put("deviceId", waterTrendQo.getSiteId());
        List<Map<String, Object>> dataList = this.deviceDataVirtualDataService.getListGroupDateAndType(condition);

        dateTableList.forEach(e -> {
            List<String> list = new ArrayList<>();
            list.add(massif.getName());
            list.add(device.getName());
            list.add(e);
            jcFactorList.forEach(k -> {
                List<Map<String, Object>> mapList = dataList.stream().filter(b -> (
                                b.get("date").equals(e)
                        )
                ).collect(Collectors.toList());
                Map<String, Double> valueMap = new HashMap<>();
                for (Map<String, Object> itemMap : mapList) {
                    if (itemMap.get("jcFactorId") != null) {
                        valueMap.put(itemMap.get("jcFactorId").toString(), Double.parseDouble(itemMap.get("factorValue").toString()));
                    }
                }
                if (valueMap.get(k.getId()) != null) {
                    list.add(valueMap.get(k.getId())+"");
                } else {
                    list.add("");
                }
            });
            bodyList.add(list);

        });

        jsonObject.put("header", headerList);
        jsonObject.put("body", bodyList);
        Map<String,Object> map = jsonObject;
        response.setHeader("Content-Disposition", "attachment; filename=hjInfoExcel.xlsx");
        // 响应类型,编码
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

        EasyExcel.write(response.getOutputStream()).head((List<List<String>>) map.get("header")).sheet("环境历史监测表").doWrite((List<List<String>>) map.get("body"));
    }


}
